package cn.iocoder.yudao.module.promotion.redpacket.dao;

import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.framework.business.basic.dao.mapper.CoreMapper;
import cn.iocoder.yudao.framework.business.basic.dao.query.CoreLambdaQueryWrapper;
import cn.iocoder.yudao.module.api.promotion.redpacket.enums.RedPacketSourceEnum;
import cn.iocoder.yudao.module.promotion.redpacket.pojo.po.RedPacketRecord;
import jakarta.annotation.Nullable;
import org.apache.ibatis.annotations.Mapper;

import java.time.LocalDateTime;
import java.util.List;

/**
 * <pre>
 * OOoO0OOoO0OOOooo0oOOOO0OOOOO0oooOO0ooOOO0Ooooo0OOOOo0ooooO0OOooo0Ooooo0OOOOO
 * Mapper 接口
 * OOoO0OOoO0OOOooo0oOOOO0OOOOO0oooOO0ooOOO0Ooooo0OOOOo0ooooO0OOooo0Ooooo0OOOOO
 * </pre>
 *
 * @author 山野羡民（1032694760@qq.com）
 * @since 2025/06/21
 */
@Mapper
public interface RedPacketRecordMapper extends CoreMapper<RedPacketRecord> {

    default boolean existsNewCustomerRedPacket(Long userId, Long shopId) {
        Long count = selectCount(new CoreLambdaQueryWrapper<RedPacketRecord>()
                .eq(RedPacketRecord::getUserId, userId)
                .eq(RedPacketRecord::getShopId, shopId)
                .eq(RedPacketRecord::getSource, RedPacketSourceEnum.NEW_CUSTOMER_BEFORE.getValue()));
        return count != null && count > 0;
    }

    default List<RedPacketRecord> selectListByExpired() {
        return selectList(new CoreLambdaQueryWrapper<RedPacketRecord>()
                .le(RedPacketRecord::getExpiredTime, LocalDateTime.now())
        );
    }

    /**
     * 总共的红包
     */
    default int sumTotalAmount(Long userId, @Nullable Long shopId) {
        CoreLambdaQueryWrapper<RedPacketRecord> wrapper = new CoreLambdaQueryWrapper<>();
        wrapper.select(RedPacketRecord::getAmount);
        wrapper.eq(RedPacketRecord::getUserId, userId);
        wrapper.eqIfPresent(RedPacketRecord::getShopId, shopId);
        List<RedPacketRecord> list = selectList(wrapper);
        if (CollUtil.isEmpty(list)) {
            return 0;
        }
        return list.stream().mapToInt(RedPacketRecord::getAmount).sum();
    }

    /**
     * “已生效+未过期”的红包中包含了“未使用+已使用”的红包
     */
    default int sumUnusedAndUsedAmount(Long userId, @Nullable Long shopId) {
        CoreLambdaQueryWrapper<RedPacketRecord> wrapper = new CoreLambdaQueryWrapper<>();
        wrapper.select(RedPacketRecord::getAmount);
        wrapper.eq(RedPacketRecord::getUserId, userId);
        wrapper.eqIfPresent(RedPacketRecord::getShopId, shopId);
        wrapper.le(RedPacketRecord::getEffectTime, LocalDateTime.now());
        wrapper.gt(RedPacketRecord::getExpiredTime, LocalDateTime.now());
        List<RedPacketRecord> list = selectList(wrapper);
        if (CollUtil.isEmpty(list)) {
            return 0;
        }
        return list.stream().mapToInt(RedPacketRecord::getAmount).sum();
    }

    /**
     * 未生效的红包
     */
    default int sumUneffectedAmount(Long userId, @Nullable Long shopId) {
        CoreLambdaQueryWrapper<RedPacketRecord> wrapper = new CoreLambdaQueryWrapper<>();
        wrapper.select(RedPacketRecord::getAmount);
        wrapper.eq(RedPacketRecord::getUserId, userId);
        wrapper.eqIfPresent(RedPacketRecord::getShopId, shopId);
        wrapper.gt(RedPacketRecord::getEffectTime, LocalDateTime.now());
        List<RedPacketRecord> list = selectList(wrapper);
        if (CollUtil.isEmpty(list)) {
            return 0;
        }
        return list.stream().mapToInt(RedPacketRecord::getAmount).sum();
    }

    /**
     * “已过期”的红包中可能包含了“已使用”的红包，因此真正“已过期”的红包需要排除“已使用”的红包
     */
    default int sumExpiredAndUsedAmount(Long userId, @Nullable Long shopId) {
        CoreLambdaQueryWrapper<RedPacketRecord> wrapper = new CoreLambdaQueryWrapper<>();
        wrapper.select(RedPacketRecord::getAmount);
        wrapper.eq(RedPacketRecord::getUserId, userId);
        wrapper.eqIfPresent(RedPacketRecord::getShopId, shopId);
        wrapper.le(RedPacketRecord::getExpiredTime, LocalDateTime.now());
        List<RedPacketRecord> list = selectList(wrapper);
        if (CollUtil.isEmpty(list)) {
            return 0;
        }
        return list.stream().mapToInt(RedPacketRecord::getAmount).sum();
    }

    default int sumAmountByTradeNo(String tradeNo) {
        CoreLambdaQueryWrapper<RedPacketRecord> wrapper = new CoreLambdaQueryWrapper<>();
        wrapper.select(RedPacketRecord::getAmount);
        wrapper.eqIfPresent(RedPacketRecord::getFromTradeNo, tradeNo);
        List<RedPacketRecord> list = selectList(wrapper);
        if (CollUtil.isEmpty(list)) {
            return 0;
        }
        return list.stream().mapToInt(RedPacketRecord::getAmount).sum();
    }

}
